<?php
/*
Plugin Name: WP-prettyPhoto
Plugin URI: http://blog.fusi0n.org/category/wp-prettyphoto
Description: WP-prettyPhoto allows you to use <a href="http://www.no-margin-for-errors.com/projects/prettyPhoto/" alt="prettyPhoto">prettyPhoto</a> by <a href="http://www.no-margin-for-errors.com/">Stéphane Caron</a>, a jQuery-powered Lightbox clone with WordPress.
Version: 1.3.2
Author: Pier-Luc Petitclerc
Author URI: http://blog.fusi0n.org
Text Domain: wp-prettyphoto
*/


if (!class_exists('WP_prettyPhoto')) {
  if (!defined('WP_CONTENT_URL')) { define('WP_CONTENT_URL', get_option('wpurl').'/wp-content'); }
  if (!defined('WP_CONTENT_DIR')) { define('WP_CONTENT_DIR', ABSPATH.'wp-content'); }
  if (!defined('WPPP_PATH')) { define('WPPP_PATH', WP_CONTENT_DIR.'/plugins/'.plugin_basename(dirname(__FILE__).'/')); }
  if (!defined('WPPP_URL')) { define('WPPP_URL',  WP_CONTENT_URL.'/plugins/'.plugin_basename(dirname(__FILE__))); }

  class WP_prettyPhoto {

    /**
     * @var array WP-prettyPhoto Options
     * @static
     * @access public
     * @since 1.3
    */
    static public $opts;

    /**
     * Class constructor
     * Sets default options, add filters and options page.
     * @author Pier-Luc Petitclerc <pL@fusi0n.org>
     * @param null
     * @return void
     * @since 1.2
     * @access public
    */
    public function __construct() {
      // Default values
      $opts = self::_getOptions(array('values'=>true,'defaults'=>true));
      foreach ($opts as $k=>$v) { add_option($k, $v); }
      $this->opts = self::_getOptions(array('values'=>true,'defaults'=>false));
      if (!is_admin() && !$this->is_mobile()) {
        if ($this->opts['wppp_jsreplace'] == 1) {
          // jQuery - removing to make sure we're using 1.3.2
          wp_deregister_script('jquery');
          wp_register_script('jquery', WPPP_URL.'/js/jquery-1.3.2.min.js', false, '1.3.2');
          wp_enqueue_script('jquery');
        }

        // prettyPhoto JavaScript
        wp_register_script('prettyphoto', WPPP_URL.'/js/jquery.prettyPhoto.js', array('jquery'), '2.4.3');
        wp_enqueue_script('prettyphoto');
        // prettyPhoto CSS
        wp_enqueue_style('prettyphoto', WPPP_URL.'/css/prettyPhoto.css', false, '2.4');

        // Enable PNG transparency hook if we're running with IE6
        if ((strpos($this->opts['wppp_theme'], 'dark_') !== false) && ($this->is_ie6())) {
          wp_register_script('belatedpng', WPPP_URL.'/js/DD_belatedPNG_0.0.7a-min.js', array('prettyphoto'), '0.0.7a');
          wp_enqueue_script('belatedpng');
        }
      }
      if (is_admin()) {
        $currentLocale = get_locale();
        if (!empty($currentLocale)) {
          $moFile = WPPP_PATH.'lang/wp-prettyphoto-'.$currentLocale.".mo";
          if (@file_exists($moFile) && is_readable($moFile)) { load_plugin_textdomain('wp-prettyphoto', $moFile); }
        }
      }
      add_action('wp_head', array(&$this, 'wppp_styles'));
      add_action('admin_head', array(&$this, 'wppp_add_options_page'));
      
      if ((($this->opts['wppp_automate_all'] == 1) || ($this->opts['wppp_automate_img'] == 1) || ($this->opts['wppp_automate_swf'] == 1) ||
            ($this->opts['wppp_automate_mov'] == 1) || ($this->opts['wppp_automate_yt'] == 1) || ($this->opts['wppp_automate_ext'] == 1)) && (!$this->is_mobile())) {
        add_filter('the_content', array(&$this, 'wppp_content_hook'), 99, 1);
        add_filter('the_excerpt', array(&$this, 'wppp_content_hook'), 99, 1);
      }
    }

    /**
     * Adds a 'Settings' link to the plugins row
     * @param array $links List of plugins to be displayed in the page
     * @param string $file Filename of the plugin currently being parsed/displayed
     * @return array Same thing as $links, but with our Settings link with it.
     * @example add_action('admin_head', 'wppp_add_options_page');
     * @author Joost de Valk
     * @link http://yoast.com/wordpress/enhanced-wordpress-contact-form/
     * @since 1.0
     * @access public
    */
    public function wppp_admin_hook($links, $file) {
      static $this_plugin;
      if (!$this_plugin) { $this_plugin = plugin_basename(__FILE__); }
      if ($file == $this_plugin) {
        $settings_link = '<a href="options-general.php?page='.plugin_basename(dirname(__FILE__)).'/wpppopt.php">' . __('Settings') . '</a>';
        array_unshift($links, $settings_link);
      }
      return $links;
    }
  
    /**
     * Adds the plugin's option page in the 'Settings' menu of the Admin
     * @param null
     * @return void
     * @author Rupert Morris
     * @since 1.0
     * @access public
    */
    public function wppp_add_options_page() {
      add_options_page('WP-prettyPhoto Options', 'WP-prettyPhoto', 'manage_options', WPPP_PATH.'wpppopt.php');
      add_filter( 'plugin_action_links', array(&$this,'wppp_admin_hook'), 10, 2 );
    }

    /**
     * Replaces occurences of $wppp_rel with the prettyPhoto rel hook
     * @param string $content Post/page contents
     * @return string Prettified post/page contents
     * @author Rupert Morris
     * @author Tanin "Regular Expression God"
     * @author Pier-Luc Petitclerc <pL@fusi0n.org>
     * @since 1.0
     * @link http://0xtc.com/2008/05/27/auto-lightbox-function.xhtml
     * @access public
    */
    public function wppp_content_hook($content) {
      $fileTypes        = self::_getFileTypes(array('type'=>'all','context'=>true));
      $pattern          = array();
      $pattern[]        = "/<a(.*?)href=('|\")([A-Za-z0-9\/_\.\~\:-]*?)($fileTypes)('|\")(.*?)>/i";
      $pattern[]        = "/<a(.*?)href=('|\")([A-Za-z0-9\/_\.\~\:-]*?)($fileTypes)('|\")(.*?)(rel=('|\")".$this->opts['wppp_rel']."(.*?)('|\"))([ \t\r\n\v\f]*?)((rel=('|\")".$this->opts['wppp_rel']."(.*?)('|\"))?)([ \t\r\n\v\f]?)([^\>]*?)>/i";
      if (get_option('wppp_automate_yt')) { $pattern[] = '/<a(.*?)href=(\'|")(http:\/\/www\.youtube\.com\/watch\?v=[A-Za-z0-9]*)(\'|")(.*?)>/i'; }
      if (get_option('wppp_automate_ext')) { $pattern[] = '/<a(.*?)href=(\'|")(.*iframe=true.*)(\'|")(.*?)>/i'; }
      return preg_replace_callback($pattern, array(&$this,'_regexCallback'), $content);
    }

    /**
     * Callback function used to detect whether a string contains a link to a _blank target
     * @param array $matches Regular Expression matches from preg_replace()
     * @return bool True if _blank was found in matches, false if it wasn't
     * @global object $post
     * @author Pier-Luc Petitclerc <pL@fusi0n.org>
     * @see wppp_content_hook
     * @since 1.2.1
     * @access private
    */
    private function _regexCallback($matches) {
      global $post;
      $pattern        = array();
      $replacement    = array();
      $pattern[]      = "/<a(.*?)href=('|\")([A-Za-z0-9\/_\.\~\:-]*?)($fileTypes)('|\")(.*?)>/i";
      $pattern[]      = "/<a(.*?)href=('|\")([A-Za-z0-9\/_\.\~\:-]*?)($fileTypes)('|\")(.*?)(rel=('|\")".$this->opts['wppp_rel']."(.*?)('|\"))([ \t\r\n\v\f]*?)((rel=('|\")".$this->opts['wppp_rel']."(.*?)('|\"))?)([ \t\r\n\v\f]?)([^\>]*?)>/i";
      $replacement[]  = '<a$1href=$2$3$4$5$6 rel="'.$this->opts['wppp_rel'].'[g'.$post->ID.']">';
      $replacement[]  = '<a$1href=$2$3$4$5$6$7>';

      if (get_option('wppp_automate_yt')) {
        $pattern[]    = '/<a(.*?)href=(\'|")(http:\/\/www\.youtube\.com\/watch\?v=[A-Za-z0-9]*)(\'|")(.*?)>/i';
        $pattern[]    = "/<a(.*?)href=('|\")(http:\/\/www\.youtube\.com\/watch\?v=[A-Za-z0-9]*)('|\")(.*?)(rel=('|\")".$this->opts['wppp_rel']."(.*?)('|\"))([ \t\r\n\v\f]*?)((rel=('|\")".$this->opts['wppp_rel']."(.*?)('|\"))?)([ \t\r\n\v\f]?)([^\>]*?)>/i";
        $replacement[]= '<a$1href=$2$3$4$5 rel="'.$this->opts['wppp_rel'].'[g'.$post->ID.']">';
        $replacement[]= '<a$1href=$2$3$4$5$6$7>';
      }
      if (get_option('wppp_automate_ext')) {
        $pattern[]    = '/<a(.*?)href=(\'|")(.*iframe=true.*)(\'|")(.*?)>/i';
        $pattern[]    = "/<a(.*?)href=('|\")(.*iframe=true.*)(.*?)(rel=('|\")".$this->opts['wppp_rel']."(.*?)('|\"))([ \t\r\n\v\f]*?)((rel=('|\")".$this->opts['wppp_rel']."(.*?)('|\"))?)([ \t\r\n\v\f]?)([^\>]*?)>/i";
        $replacement[]= '<a$1href=$2$3$4$5 rel="'.$this->opts['wppp_rel'].'[g'.$post->ID.']">';
        $replacement[]= '<a$1href=$2$3$4$5$6$7>';
      }
      return !strpos($matches['0'], '_blank')? preg_replace($pattern,$replacement,$matches['0']) : $matches['0'];
    }

    /**
     * Gets file extension(s) associated with media type
     * @param array $opts Options array
     * @param string $opts['type'] Media Type (mov, swf, img or all)
     * @param bool $opts['context'] Validate against configuration
     * @return string Pipe-separated file extension(s)
     * @author Pier-Luc Petitclerc <pL@fusi0n.org>
     * @since 1.3
     * @access private
    */
    private function _getFileTypes($opts=array()) {
      switch ($opts['type']) {
        case 'mov':
          return $opts['context']? $this->opts['wppp_automate_mov']? '\.mov' : false : '\.mov';
        break;
        case 'swf':
          return $opts['context']? $this->opts['wppp_automate_swf']? '\.swf' : false : '\.swf';
        break;
        case 'img':
          return $opts['context']? $this->opts['wppp_automate_img']? '\.bmp|\.gif|\.jpg|\.jpeg|\.png' : false : '\.bmp|\.gif|\.jpg|\.jpeg|\.png';
        break;
        case 'all':
        default:
          return self::_getFileTypes(array('type'=>'mov', $opts['context'])).'|'.self::_getFileTypes(array('type'=>'swf', $opts['context'])).'|'.self::_getFileTypes(array('type'=>'img', $opts['context']));
      }
    }

    /**
     * Adds prettyPhoto in the page that is being viewed
     * @param null
     * @return void
     * @author Pier-Luc Petitclerc <pL@fusi0n.org>
     * @example add_action('wp_head', 'wppp_styles');
     * @link http://www.no-margin-for-errors.com/projects/prettyPhoto/#howtouse
     * @since 1.0
     * @access public
    */
    public function wppp_styles() {
      $ie6 = <<<EOHEAD
        <!--[if IE 6]>
            <script>
                    DD_belatedPNG.fix('div.pictureHolder .top .left,div.pictureHolder .top .right,div.pictureHolder .top .left,div.pictureHolder .bottom .left,div.pictureHolder .bottom .right,div.pictureHolder .content a.close,div.pictureHolder .content .details .nav a.arrow_next,div.pictureHolder .content .details .nav a.arrow_previous,div.pictureHolder .content,div.pictureHolder .bottom .middle,div.pictureHolder .top .middle'); 
            </script>
        <![endif]-->
EOHEAD;

      $output = <<<EOHTML

        <script type="text/javascript" charset="utf-8">
          $(document).ready(function(){
            $("a[rel^='{$this->opts['wppp_rel']}']").prettyPhoto({
              animationSpeed: '{$this->opts['wppp_speed']}', /* fast/slow/normal */
              padding: {$this->opts['wppp_padding']}, /* padding for each side of the picture */
              opacity: {$this->opts['wppp_opacity']}, /* Value betwee 0 and 1 */
              showTitle: {$this->opts['wppp_title']}, /* true/false */
              allowresize: {$this->opts['wppp_resize']}, /* true/false */
              counter_separator_label: '{$this->opts['wppp_counterlabel']}', /* The separator for the gallery counter 1 "of" 2 */
              theme: '{$this->opts['wppp_theme']}' /* light_rounded / dark_rounded / dark_square */
            });
          });
        </script>
EOHTML;
      echo ((strpos($this->opts['wppp_theme'], 'dark_') !== false) && ($this->is_ie6()))? $ie6.$output : $output;;
    }

    /**
     * Fetches a list of installed prettyPhoto themes
     * @param null
     * @return array Numeric array containing directory names of installed themes
     * @author Pier-Luc Petitclerc <pL@fusi0n.org>
     * @since 1.1
     * @static
     * @access public
    */
    static public function _getThemes() {
      $themes = array();
      $dir = scandir(WPPP_PATH.'images/prettyPhoto');
      foreach ($dir as $key=>$dirname) {
        if ((strlen($dirname) > 2) && is_dir(WPPP_PATH.'images/prettyPhoto/'.$dirname)) { $themes[] = $dirname; }
      }
      return $themes;
    }

    /**
     * Lists the options used by WP-prettyPhoto
     * @param array Options array
     * @param bool $opts['values'] Return options' values?
     * @param bool $opts['defaults'] Return options' default values?
     * @return array List of options
     * @static
     * @access public
     * @author Pier-Luc Petitclerc <pL@fusi0n.org>
     * @since 1.3
    */
    static public function _getOptions($opts=array()) {
      $wppp_options = array('wppp_automate_all', 'wppp_automate_img', 'wppp_automate_swf',
                            'wppp_automate_mov', 'wppp_automate_yt', 'wppp_automate_ext',
                            'wppp_rel', 'wppp_speed', 'wppp_padding', 'wppp_opacity',
                            'wppp_title', 'wppp_resize', 'wppp_counterlabel', 'wppp_theme',
                            'wppp_jsreplace');
      if ($opts['values']) {
        $wppp_options_values = array();
        if ($opts['defaults']) {
          $wppp_options_values['wppp_automate_all'] = 0;
          $wppp_options_values['wppp_automate_img'] = 1;
          $wppp_options_values['wppp_automate_swf'] = 1;
          $wppp_options_values['wppp_automate_mov'] = 1;
          $wppp_options_values['wppp_automate_yt']  = 1;
          $wppp_options_values['wppp_automate_ext'] = 0;
          $wppp_options_values['wppp_rel']          = 'wp-prettyPhoto';
          $wppp_options_values['wppp_speed']        = 'normal';
          $wppp_options_values['wppp_padding']      = '20';
          $wppp_options_values['wppp_opacity']      = '0.35';
          $wppp_options_values['wppp_title']        = 1;
          $wppp_options_values['wppp_resize']       = 1;
          $wppp_options_values['wppp_counterlabel'] = '/';
          $wppp_options_values['wppp_theme']        = 'dark_rounded';
          $wppp_options_values['wppp_jsreplace']    = 1;
        }
        else {
          foreach ($wppp_options as $opt) { $wppp_options_values[$opt] = get_option($opt)? get_option($opt) : 0; }
          self::$opts = $wppp_options_values;
        }
        return $wppp_options_values;
      }
      else { return $wppp_options; }
    }
    /**
     * Detects if user is using Microsoft Internet Explorer 6
     * @param null
     * @return bool True if user is using MSIE6, False if he is not
     * @author Pier-Luc Petitclerc <pL@fusi0n.org>
     * @since 1.1
     * @access private
    */
    private function is_ie6() {
      return strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE 6') !== false? true : false;
    }

    /**
     * Detects if user is using a known mobile browser
     * @param null
     * @return bool True if user is using a mobile browser, false if he is not
     * @author Andy Moore <andy@andymoore.info>
     * @author Pier-Luc Petitclerc <pL@fusi0n.org>
     * @link http://detectmobilebrowsers.mobi
     * @since 1.1
     * @access private
    */
    private function is_mobile() {
      $ua = $_SERVER['HTTP_USER_AGENT'];
      $a  = $_SERVER['HTTP_ACCEPT'];
      $b  = array(array('ipod', 'iphone', 'android', 'opera mini', 'blackberry'),
                  array('palm os', 'palm', 'hiptop', 'avantgo', 'plucker', 'xiino', 'blazer', 'elaine',
                        'windows ce; ppc;', 'windows ce; smartphone;', 'windows ce; iemobile',
                        'up.browser', 'up.link', 'mmp', 'symbian', 'smartphone', 'midp', 'wap', 'vodafone', 'o2', 'pocket', 'kindle', 'mobile', 'pda', 'psp', 'treo'));
      $r  = array('('.implode($b['0'], ')|(').')',
                  '/('.implode($b['1'], '|').')/i');
      return (eregi($r['0'], $ua) || preg_match($r['1'], $ua) ||
              ((strpos($a,'text/vnd.wap.wml')>0) || (strpos($a,'application/vnd.wap.xhtml+xml')>0)) ||
              isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE']))? true : false;
    }
  }

  // Fire in the hole!
  $wppp = new WP_prettyPhoto();
}
